package com.dubbo.soa.spring.configBean;

import com.dubbo.soa.advice.InvokeInvocationHandler;
import com.dubbo.soa.invoke.HttpInvoke;
import com.dubbo.soa.invoke.Invoke;
import com.dubbo.soa.invoke.NettyInvoke;
import com.dubbo.soa.invoke.RmiInvoke;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

public class Reference implements FactoryBean,ApplicationContextAware {
    private String id;
   private String intf;
   private String check;
   private String protocol;

   private Invoke invoke;

   private ApplicationContext applicationContext;
   private static Map<String,Invoke> invokeMaps = new HashMap<String, Invoke>();
   //自定义通信协议，常见的三种
   static {
       invokeMaps.put("http",new HttpInvoke());
       invokeMaps.put("rmi",new RmiInvoke());
       invokeMaps.put("netty",new NettyInvoke());
       invokeMaps.put("通信xyzw协议",new NettyInvoke());
   }
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getIntf() {
        return intf;
    }

    public void setIntf(String intf) {
        this.intf = intf;
    }

    public String getCheck() {
        return check;
    }

    public void setCheck(String check) {
        this.check = check;
    }

    public String getProtocol() {
        return protocol;
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }
    //返回一个对象，并被spring容器管理
    public Object getObject() throws Exception {
       //假如未配置，则去全局配置Protocol去获取全局配置
       if(protocol != null && !"".equals(protocol)){
          invoke = invokeMaps.get(protocol);
       }else {
           Protocol protocol = applicationContext.getBean(Protocol.class);
           if(protocol != null){
               invoke = invokeMaps.get(protocol.getName());
           }else{
               //假如全局里面也没有配置，则默认使用netty协议
               invoke = invokeMaps.get("netty");
           }
       }
        Object proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(),new Class<?>[]{Class.forName(intf)},
                new InvokeInvocationHandler(invoke,this));
        return proxy;
    }
    //返回实例的类型
    public Class<?> getObjectType() {
        try {
            if(intf != null && !"".equals(intf)){

                    return Class.forName(intf);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
    //是否单例
    public boolean isSingleton() {
        return true;
    }
    //继承ApplicationContextAware，获得上下文
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
       this.applicationContext = applicationContext;
    }
}
